#!/usr/bin/env python3
# -*- encoding: utf-8 -*-
'''
@File    :   Config.py
@Time    :   2020/11/06
@Author  :   wenke wang
@Version :   1.0
@Desc    :   配置模块
'''

# here put the import lib
import csv, json
from enum import Enum, IntEnum
from copy import deepcopy

class ReeFormula(Enum):
    """
    BEE/REE公式类型
    """

    # 经典
    CLASSIC = 1
    # 简便
    NORMAL = 2

class Gender(IntEnum):
    """
    性别枚举
    """

    # 男
    M = 1
    # 女
    F = 2

    @classmethod
    def tryparse(cls, value):
        try:
            return Gender(value)
        except ValueError:
            return None

    @classmethod
    def isvalidvalue(cls, value, return_gender_if_valid=False):
        gender = Gender.tryparse(value)
        if not gender:
            return False, None if return_gender_if_valid else False
        else:
            return True, gender if return_gender_if_valid else True

class Pal(IntEnum):
    """
    身体活动水平枚举
    """

    # 轻度
    LIGHT = 1
    # 中度
    MODERATE = 2
    # 重度
    SEVERE = 3

    @classmethod
    def tryparse(cls, value):
        try:
            return Pal(value)
        except ValueError:
            return None

    @classmethod
    def isvalidvalue(cls, value, return_pal_if_valid=False):
        pal = Pal.tryparse(value)
        if not pal:
            return False, None if return_pal_if_valid else False
        else:
            return True, pal if return_pal_if_valid else True

class PalCoefficientUtil():
    """
    身体活动水平表
    """

    def __init__(self, load_path):
        self.__table = self.__load(load_path)

    def __load(self, load_path):
        table = []
        with open(load_path, "r", encoding="utf-8") as f:
            rows = csv.reader(f)
            # 读取首行-标题
            next(rows)
            for row in rows:
                table.append({
                    "age_low": int(row[0]),
                    "age_high": int(row[1]),
                    "pal_light": float(row[2]),
                    "pal_moderate": float(row[3]),
                    "pal_severe": float(row[4])
                })
        return table

    def get_coe(self, age, pal):
        """
        获取身体活动水平系数
        """
        
        for row in self.__table:
            if age >= row["age_low"] and age <= row["age_high"]:
                co_row = row
                break
        
        if not co_row:
            return None

        co_value = co_row["pal_%s" % pal.name.lower()]
        if co_value < 0:
            return None
        
        return co_value

class Energy():
    """
    食物能量交换份数，
    rand_percent中的low和high是整形计算所以不需要改成字符串，直接使用即可；
    其余数值均为浮点数计算，float类型会导致精度丢失，故使用字符串保存并在计算时转为Decimal类型
    """

    def __init__(self, setting_path):
        with open(setting_path, "r", encoding="utf-8") as fp:
            self.__setting = json.load(fp)

    @property
    def setting(self):
        return self.__setting

class FoodNumSetting():
    """
    每1份食物重量
    """

    def __init__(self, setting_path):
        with open(setting_path, "r", encoding="utf-8") as fp:
            self.__setting = json.load(fp)

    @property
    def setting(self):
        return self.__setting